<template>
  <div>
    <el-form ref="elForm" :model="formData" :rules="rules" size="medium" label-width="100px">
      <el-form-item label="用户" prop="userId">
        <el-select v-model="formData.userId" placeholder="请选择用户（可输入姓名搜索）" clearable filterable remote :remote-method="userRemoteMethod" :loading="userLoading" :style="{width: '100%'}">
          <el-option v-for="(item, index) in userOptions" :key="index" :label="item.label" :value="item.value" />
        </el-select>
      </el-form-item>
      <el-form-item label="性格标签" prop="personality">
        <el-input v-model="formData.personality" placeholder="请输入性格标签" clearable :style="{width: '100%'}">
        </el-input>
      </el-form-item>
      <el-form-item label="兴趣爱好" prop="hobbies">
        <el-input v-model="formData.hobbies" placeholder="请输入兴趣爱好" clearable :style="{width: '100%'}">
        </el-input>
      </el-form-item>
      <el-form-item label="备注" prop="remark">
        <el-input v-model="formData.remark" type="textarea" placeholder="如果需要修改个人信息，直接提交修改过的信息即可" :autosize="{minRows: 4, maxRows: 4}" :style="{width: '100%'}"></el-input>
      </el-form-item>
      <el-form-item size="large">
        <el-button type="primary" @click="submitForm">提交</el-button>
        <el-button @click="resetForm">重置</el-button>
      </el-form-item>
    </el-form>
    <el-table v-if="previewVisible" :data="previewList" style="width: 100%; margin-top: 16px;" v-loading="previewLoading">
      <el-table-column type="index" width="55" align="center" />
      <el-table-column label="关联用户" align="center" prop="userName" />
      <el-table-column label="性格标签" align="center" prop="personality" />
      <el-table-column label="兴趣爱好" align="center" prop="hobbies" />
      <el-table-column label="备注" align="center" prop="remark" />
    </el-table>
    <div v-if="recommendVisible" style="margin-top: 16px;">
      <div style="font-weight: 600; margin-bottom: 8px;">为你推荐社团</div>
      <el-row :gutter="12" v-loading="recommendLoading">
        <el-col :span="8" v-for="club in recommendedClubs" :key="club.id" style="margin-bottom: 12px;">
          <el-card shadow="hover">
            <div style="display:flex; justify-content:space-between; align-items:center;">
              <div style="font-size: 15px; font-weight: 600;">{{ club.name }}</div>
              <el-popover placement="left" width="420" trigger="hover" @show="loadClubActivities(club)">
                <div style="margin-bottom:6px; font-weight:600;">社团简介</div>
                <div style="white-space: pre-line;">{{ club.introduction || '暂无介绍' }}</div>
                <div style="margin-top:10px; font-weight:600;">往期活动</div>
                <div v-if="club.activitiesLoading" style="padding:8px 0;">加载活动中...</div>
                <ul v-else style="padding-left: 16px; margin: 6px 0;">
                  <li v-for="(act, idx) in club.activities" :key="idx">{{ act.title }}（{{ act.activityTime }}）</li>
                  <li v-if="!club.activities || !club.activities.length">暂无活动</li>
                </ul>
                <div slot="reference" style="cursor:pointer; color:#409EFF;">悬浮查看详情</div>
              </el-popover>
            </div>
            <div style="margin:8px 0; display:flex; flex-wrap:wrap; align-items:center;">
              <template v-for="(t, i) in club.tags">
                <el-tag :key="'tag-'+i" type="info" style="margin:0 6px 6px 0;">{{ t }}</el-tag>
                <el-button :key="'btn-'+i" type="text" size="mini" @click="goApply(club)" style="margin-right:12px;">去报名</el-button>
              </template>
            </div>
            <div style="display:flex; justify-content:space-between; align-items:center;">
              <div>活跃度：{{ club.activityScore }}</div>
              <div style="color:#909399;">匹配度：{{ club.matchScore }}</div>
            </div>
          </el-card>
        </el-col>
      </el-row>
    </div>
  </div>
</template>
<script>
import { addProfile, listProfile, delProfile } from '@/api/club/profile'
import { listUser, getUser } from '@/api/system/user'
import { listInfo } from '@/api/club/info'
import { listActivity } from '@/api/club/activity'
export default {
  components: {},
  props: [],
  data() {
    return {
      formData: {
        userId: undefined,
        personality: '',
        hobbies: '',
        remark: '',
      },
      rules: {
        userId: [{ required: true, message: '请选择用户', trigger: 'change' }],
        personality: [{ required: true, message: '请输入性格标签', trigger: 'blur' }],
        hobbies: [{ required: true, message: '请输入兴趣爱好', trigger: 'blur' }],
        // remark: [{ required: true, message: '请输入备注', trigger: 'blur' }],
      },
      userOptions: [],
      userLoading: false,
      previewVisible: false,
      previewList: [],
      previewLoading: false
      ,recommendVisible: false,
      recommendLoading: false,
      recommendedClubs: []
    }
  },
  computed: {},
  watch: {},
  created() {
    this.loadInitialUsers()
  },
  mounted() {},
  methods: {
    submitForm() {
      this.$refs['elForm'].validate(valid => {
        if (!valid) return
        const uid = this.formData.userId
        const snapshot = { userId: this.formData.userId, personality: this.formData.personality, hobbies: this.formData.hobbies, remark: this.formData.remark }
        this.upsertProfile().then(() => {
          this.$modal.msgSuccess('提交成功')
          this.fetchPreview(uid)
          this.fetchRecommendations(snapshot)
          this.resetForm()
        })
      })
    },
    resetForm() {
      this.$refs['elForm'].resetFields()
    },
    loadInitialUsers() {
      const query = { pageNum: 1, pageSize: 20 }
      listUser(query).then(res => {
        const rows = res.rows || []
        this.userOptions = rows.map(u => ({ label: u.nickName || u.userName || `用户${u.userId}`, value: u.userId }))
      })
    },
    userRemoteMethod(query) {
      if (!query) {
        this.loadInitialUsers()
        return
      }
      this.userLoading = true
      const params = { pageNum: 1, pageSize: 20, userName: query }
      listUser(params).then(res => {
        const rows = res.rows || []
        this.userOptions = rows.map(u => ({ label: u.nickName || u.userName || `用户${u.userId}`, value: u.userId }))
        this.userLoading = false
      }).catch(() => {
        this.userLoading = false
      })
    },
    checkDuplicateUser() {
      const query = { pageNum: 1, pageSize: 1, userId: this.formData.userId }
      return listProfile(query).then(res => {
        const total = res.total || 0
        return total === 0
      })
    },
    upsertProfile() {
      const query = { pageNum: 1, pageSize: 1, userId: this.formData.userId }
      return listProfile(query).then(res => {
        const rows = res.rows || []
        if (rows.length) {
          const id = rows[0].id
          return delProfile(id).then(() => addProfile(this.formData))
        } else {
          return addProfile(this.formData)
        }
      })
    },
    fetchPreview(userId) {
      if (!userId) {
        this.previewVisible = false
        this.previewList = []
        return
      }
      this.previewLoading = true
      const query = { pageNum: 1, pageSize: 5, userId }
      listProfile(query).then(res => {
        const rows = res.rows || []
        const mapped = rows.map(r => {
          const opt = this.userOptions.find(u => u.value === r.userId)
          return { ...r, userName: opt ? opt.label : '' }
        })
        this.previewList = mapped
        const missing = mapped.filter(x => !x.userName)
        if (missing.length) {
          Promise.all(missing.map(x => getUser(x.userId))).then(arr => {
            arr.forEach((resp, idx) => {
              const d = resp.data || {}
              const id = missing[idx].userId
              const name = d.nickName || d.userName || ''
              const target = this.previewList.find(p => p.userId === id)
              if (target) target.userName = name
            })
            this.previewVisible = true
            this.previewLoading = false
          }).catch(() => {
            this.previewVisible = true
            this.previewLoading = false
          })
        } else {
          this.previewVisible = true
          this.previewLoading = false
        }
      }).catch(() => {
        this.previewLoading = false
      })
    },
    fetchRecommendations(snapshot) {
      const tokens = this.buildKeywords(snapshot)
      if (!tokens.length) {
        this.recommendVisible = false
        this.recommendedClubs = []
        return
      }
      this.recommendLoading = true
      const query = { pageNum: 1, pageSize: 999 }
      listInfo(query).then(res => {
        const rows = (res.rows || []).map(r => {
          const tagsArr = (r.tags || '').split(',').map(s => s.trim()).filter(Boolean)
          const tl = tokens.map(t => t.toLowerCase())
          const tagLower = tagsArr.map(t => t.toLowerCase())
          const setA = new Set(tl)
          const setB = new Set(tagLower)
          let inter = 0
          setA.forEach(v => { if (setB.has(v)) inter++ })
          const union = setA.size + setB.size - inter
          const jaccard = union > 0 ? inter / union : 0
          const nameL = (r.name || '').toLowerCase()
          const introL = (r.introduction || '').toLowerCase()
          let hit = 0
          tl.forEach(k => { if (nameL.includes(k) || introL.includes(k)) hit++ })
          const textHit = tl.length > 0 ? hit / tl.length : 0
          const normAct = Math.min(Math.max(Number(r.activityScore) || 0, 0), 100) / 100
          const score = 0.6 * jaccard + 0.2 * textHit + 0.2 * normAct
          return {
            id: r.id,
            name: r.name,
            introduction: r.introduction,
            tags: tagsArr,
            activityScore: r.activityScore,
            matchScore: Number(score.toFixed(2)),
            activities: [],
            activitiesLoading: false
          }
        })
        const ranked = rows.filter(x => x.matchScore > 0).sort((a, b) => b.matchScore - a.matchScore).slice(0, 6)
        this.recommendedClubs = ranked
        this.recommendVisible = ranked.length > 0
        this.recommendLoading = false
      }).catch(() => {
        this.recommendLoading = false
        this.recommendVisible = false
      })
    },
    buildKeywords(snapshot) {
      const toTokens = s => (s || '').split(/[\s,，；;]/).map(x => x.trim().toLowerCase()).filter(Boolean)
      const set = new Set([...toTokens(snapshot.personality), ...toTokens(snapshot.hobbies)])
      return Array.from(set)
    },
    loadClubActivities(club) {
      if (!club || club.activitiesLoading || (club.activities && club.activities.length)) return
      club.activitiesLoading = true
      const query = { pageNum: 1, pageSize: 5, clubId: club.id }
      listActivity(query).then(res => {
        const rows = res.rows || []
        club.activities = rows.map(a => ({ title: a.title, activityTime: a.activityTime }))
        club.activitiesLoading = false
      }).catch(() => {
        club.activitiesLoading = false
      })
    },
    goApply(club) {
      const url = `http://localhost/c/application?clubId=${club.id}`
      window.open(url, '_self')
    }
  }
}

</script>
<style>
</style>
